<!-- 
 原作者: [@cooltea](https://blog.csdn.net/apple_54470279?type=blog)
 第一次改版：[@Tloml-Starry])(https://gitee.com/Tloml-Starry)
 第二次改版：[小i](QQ: 3446914493)
  -->

<head>
    <meta charset="UTF-8">
    <title>简单日历效果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        ul {
            display: flex;
            flex-direction: row;
        }

        li {
            display: block;
            list-style: none;
        }

        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            font-family: 'Arial', sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }

        .cal-container {
            display: flex;
            flex-direction: column;
            width: 600px;
            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
            background-color: #ffffff;
            border-radius: 20px;
            overflow: hidden;
        }

        .cal-container .year-month {
            position: relative;
            width: 100%;
            height: 200px;
            background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%);
            /* 修改为蓝粉色渐变色 */
            border-top-left-radius: 20px;
            border-top-right-radius: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            color: white;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }

        .cal-container .year-month>div:first-child>span {
            display: block;
            margin-bottom: 5px;
            font-weight: 700;
        }

        .cal-container .year-month>div:first-child>span:first-child {
            font-size: 40px;
        }

        .cal-container .year-month>div:first-child>span:last-child {
            font-size: 25px;
        }

        .cal-container .year-month .pre,
        .cal-container .year-month .next {
            position: absolute;
            top: 50%;
            height: 40px;
            transform: translateY(-20px);
            margin: 0 20px;
            font-size: 40px;
            color: white;
            cursor: pointer;
            transition: transform 0.3s ease-in-out;
        }

        .cal-container .year-month .pre {
            left: 20px;
        }

        .cal-container .year-month .next {
            right: 20px;
        }

        .cal-container .year-month .pre:hover,
        .cal-container .year-month .next:hover {
            transform: translateY(-20px) scale(1.2);
        }

        .cal-container .weeks>ul,
        .cal-container .days>ul {
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            width: 100%;
            padding: 0 2.5px;
            background-color: #f8f9fa;
        }

        .cal-container .days>ul {
            padding: 20px 0;
            background-color: #e9ecef;
            border-bottom-left-radius: 20px;
            border-bottom-right-radius: 20px;
            backdrop-filter: blur(10px);
            background-color: rgba(255, 255, 255, 0.5);
        }

        .cal-container .weeks>ul>li {
            width: 85px;
            font-size: 20px;
            font-weight: 700;
            color: #343a40;
            text-align: center;
            line-height: 50px;
        }

        .style-default {
            width: 50px;
            height: 50px;
            margin: 0 17.5px;
            font-size: 20px;
            font-weight: 700;
            color: #343a40;
            text-align: center;
            line-height: 50px;
            border-radius: 50%;
            transition: background-color 0.3s ease-in-out, transform 0.3s ease-in-out;
        }

        .days>ul .style-default:hover {
            background-color: #dee2e6;
            transform: scale(1.1);
        }

        .cal-container .days>ul .bg-style {
            background-color: #ff6a00;
            color: white;
        }

        .cal-container .days>ul .bgg-style {
            background-color: #ff0000;
            color: white;
        }

        .cal-container .days>ul .bggg-style {
            background-color: #6c757d;
            color: white;
        }

        .no-style {
            width: 50px;
            height: 50px;
            margin: 0 17.5px;
        }
    </style>
</head>

<body>
    <div class="cal-container">
        <div class="year-month">
            <div>
                <span id="month"></span>
                <span id="year" style="position: relative;position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%) translateY(120%);"></span>
            </div>
            <div class="pre" id="pre-month">&lt;</div>
            <div class="next" id="next-month">&gt;</div>
        </div>
        <div class="weeks">
            <ul>
                <li>一</li>
                <li>二</li>
                <li>三</li>
                <li>四</li>
                <li>五</li>
                <li>六</li>
                <li>七</li>
            </ul>
        </div>
        <div class="days">
            <ul id="day"></ul>
        </div>
    </div>
    <script>
        let date = new Date();
        Y = date.getFullYear();
        M = date.getMonth();
        W = date.getDay();
        D = date.getDate();
        isSelect = true;

        let yearNow = document.getElementById("year");
        yearNow.innerHTML = Y;
        let monthNow = document.getElementById("month");
        monthNow.innerHTML = monthAndMaxDay(Y, M)[0];
        selected(isSelect);
        let days = document.getElementById("day");
        updateAllDays(Y, M);

        yearNow.addEventListener("click", function () {
            isSelect = false
            selected(isSelect);
        });
        monthNow.addEventListener("click", function () {
            isSelect = true;
            selected(isSelect);
        });

        let previous = document.getElementById("pre-month");
        previous.addEventListener("click", function () { changePage(true); });
        let next = document.getElementById("next-month");
        next.addEventListener("click", function () { changePage(false); });

        function monthAndMaxDay(year, month) {
            let month_now = "";
            let maxDay = 0;
            switch (month + 1) {
                case 1: month_now = "一月碎石日历"; maxDay = 31; break;
                case 2:
                    month_now = "二月碎石日历";
                    if (year % 4 == 0) {
                        maxDay = 29;
                    } else {
                        maxDay = 28;
                    }
                    break;
                case 3: month_now = "三月碎石日历"; maxDay = 31; break;
                case 4: month_now = "四月碎石日历"; maxDay = 30; break;
                case 5: month_now = "五月碎石日历"; maxDay = 31; break;
                case 6: month_now = "六月碎石日历"; maxDay = 30; break;
                case 7: month_now = "七月碎石日历"; maxDay = 31; break;
                case 8: month_now = "八月碎石日历"; maxDay = 31; break;
                case 9: month_now = "九月碎石日历"; maxDay = 30; break;
                case 10: month_now = "十月碎石日历"; maxDay = 31; break;
                case 11: month_now = "十一月碎石日历"; maxDay = 30; break;
                case 12: month_now = "十二月碎石日历"; maxDay = 31; break;
                default: month = "";
            }
            return [month_now, maxDay];
        }

        function getStoneDate(YEAR, MONTH) {
            const START_1 = new Date(YEAR, MONTH - 1, 1);
            const END_1 = new Date(YEAR, MONTH - 1, 15);

            const START_2 = new Date(YEAR, MONTH - 1, 16);
            const END_2 = new Date(YEAR, MONTH, 0);

            function COUNT_WEEK_DAYS(START_DATE, EMD_DATE, DAY_OF_WEEK_1, DAY_OF_WEEK_2 = null) {
                let WEEK_DAYS = [];
                let CURRENT_DATE = new Date(START_DATE);

                while (CURRENT_DATE <= EMD_DATE) {
                    const DAY_OF_WEEK = CURRENT_DATE.getDay();
                    if (DAY_OF_WEEK === DAY_OF_WEEK_1 || DAY_OF_WEEK === DAY_OF_WEEK_2) {
                        WEEK_DAYS.push(CURRENT_DATE.getDate());
                    }
                    CURRENT_DATE.setDate(CURRENT_DATE.getDate() + 1);
                }

                return WEEK_DAYS;
            }

            return [[
                ...COUNT_WEEK_DAYS(START_1, END_1, 0, 6),
                ...COUNT_WEEK_DAYS(START_2, END_2, 5, 0)
            ], [
                ...COUNT_WEEK_DAYS(START_1, END_1, 2),
                ...COUNT_WEEK_DAYS(START_2, END_2, 3)
            ]]
        }

        function updateAllDays(year, month) {
            let offset = new Date(year, month, 0).getDay();
            let maxDay = monthAndMaxDay(year, month)[1];

            for (let i = 0; i < offset; i++) {
                let day = document.createElement("li");
                day.className = "no-style";
                days.appendChild(day);
            }

            for (let i = 1; i <= maxDay; i++) {
                let day = document.createElement("li");
                let dateNow = new Date();
                const RED = getStoneDate(year, month + 1)[0]
                const BLACK = getStoneDate(year, month + 1)[1]
                if (year == dateNow.getFullYear() && month == dateNow.getMonth() && i == dateNow.getDate()) {
                    day.className = "style-default bg-style"
                } else {
                    day.className = "style-default";
                }
                day.id = i;
                day.innerText = i
                if (RED.includes(i)) {
                    day.classList.add("bgg-style");
                }
                if (BLACK.includes(i)) {
                    day.classList.add("bggg-style")
                }
                days.appendChild(day);
            }
        }

        function selected(boolean) {
            if (boolean) {
                monthNow.style.textShadow = "2px 2px 2px rgba(0, 0, 0, 0.2)";
                yearNow.style.textShadow = "none";
            } else {
                monthNow.style.textShadow = "none";
                yearNow.style.textShadow = "2px 2px 2px rgba(0, 0, 0, 0.2)";
            }
        }

        function changePage(boolean) {
            if (isSelect) {
                if (boolean) {
                    M = M - 1;
                    if (M == -1) {
                        Y--;
                        M = 11;
                    }
                } else {
                    M = M + 1;
                    if (M == 12) {
                        Y++;
                        M = 0;
                    }
                }
            } else {
                if (boolean) {
                    Y--;
                } else {
                    Y++;
                }
            }
            yearNow.innerHTML = Y;
            monthNow.innerHTML = monthAndMaxDay(Y, M)[0];
            days.innerHTML = "";
            updateAllDays(Y, M);
        }
    </script>
</body>